package com.jintoufs.service.tour.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jintoufs.dao.QueryFilters;
import com.jintoufs.dao.bill.BillInfoMapper;
import com.jintoufs.dao.customer.CustomerCouponMapper;
import com.jintoufs.dao.tour.*;
import com.jintoufs.dao.travelagency.TravelAgencyMapper;
import com.jintoufs.domain.bill.BillInfo;
import com.jintoufs.domain.constants.Constants;
import com.jintoufs.domain.constants.FullCalendar;
import com.jintoufs.domain.contacts.Contacts;
import com.jintoufs.domain.customer.Customer;
import com.jintoufs.domain.customer.CustomerCoupon;
import com.jintoufs.domain.images.Images;
import com.jintoufs.domain.tour.*;
import com.jintoufs.domain.travelagency.TravelAgency;
import com.jintoufs.service.contacts.ContactsService;
import com.jintoufs.service.image.ImageService;
import com.jintoufs.service.tour.TourRouteService;
import com.jintoufs.util.valid.ValidUtil;
import com.jintoufs.uuid.SnowflakeIdWorker;
import org.apache.commons.lang.StringUtils;
import org.cosmos.modules.exception.ServiceException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author zhenghq
 * @Time 2018-01-15 12:30
 */

@Service
@Transactional(rollbackFor = Exception.class)
public class TourRouteServiceImpl implements TourRouteService {
    @Resource
    private ContactsService contactsService;
    @Resource
    private ImageService imageService;


    @Resource
    private TourRouteMapper routeMapper;

    @Resource
    private TourRouteDayMapper dayMapper;

    @Resource
    private TourRouteDayDetailMapper dayDetailMapper;

    @Resource
    TravelAgencyMapper travelAgencyMapper;

    @Resource
    TourRoutePriceMapper tourRoutePriceMapper;

    @Resource
    TourRouteOrderMapper tourRouteOrderMapper;
    @Resource
    TourRouteOrderDetailMapper orderDetailMapper;

    @Resource
    private CustomerCouponMapper customerCouponMapper;
    @Resource
    private SnowflakeIdWorker snowflakeIdWorker;

    @Resource
    BillInfoMapper billInfoMapper;

    @Override
    public List<Map<String, Object>> getByFilter(QueryFilters filters) {
        return routeMapper.getByFilter(filters);
    }

    @Override
    public void saveRoute(Map<String, Object> params, Customer customer) throws ServiceException {
        String id;
        try {
            TourRoute route = StringUtils.isEmpty(params.get("id") + "") ? new TourRoute() :
                    routeMapper.selectByPrimaryKey(params.get("id") + "");
            route.setRouteName(params.get("routeName") + "");
            if (StringUtils.isNotEmpty(params.get("personNum") + "")) {
                route.setPersonNum(Integer.parseInt(params.get("personNum") + ""));
            }
            if (StringUtils.isNotEmpty(params.get("tourDay") + "")) {
                route.setTourDay(Integer.parseInt(params.get("tourDay") + ""));
            }
            DateFormat dfmt = new SimpleDateFormat("yyyy-MM-dd");
            if (StringUtils.isNotEmpty(params.get("startTime") + "")) {
                route.setStartTime(dfmt.parse(params.get("startTime") + ""));
            }
//            DateFormat dfmt = new SimpleDateFormat("yyyy-MM-dd");
//            route.setStartTime(dfmt.parse(params.get("startTime")+""));
//            route.setEndTime(dfmt.parse(params.get("endTime")+""));
            route.setStartPlace(params.get("startPlace") + "");
            route.setBackPlace(params.get("backPlace") + "");
            if (StringUtils.isNotEmpty(params.get("totalFee") + "")) {
                route.setTotalFee(new BigDecimal(params.get("totalFee") + ""));
            }
            if (StringUtils.isNotEmpty(params.get("marketPrice") + "")) {
                route.setMarketPrice(new BigDecimal(params.get("marketPrice") + ""));
            }
            StringBuilder typeId = new StringBuilder("");
            route.setIntroduction(params.get("introduction") + "");
            Object strings = params.get("typeId[]");

            if (!ValidUtil.isEmpty(strings)) {
                int i = 1;
                for (String s : (String[]) strings) {
                    typeId.append(s);
                    if (i < ((String[]) strings).length) {
                        typeId.append(",");
                    }
                    i++;
                }
            }else{
                typeId = new StringBuilder(params.get("typeId").toString());
            }
            route.setTypeId(typeId.toString());
            if (StringUtils.isNotEmpty(params.get("distributionPrice") + "")) {
                route.setDistributionPrice(new BigDecimal(params.get("distributionPrice") + ""));
            }
            route.setRemark(params.get("remark") + "");
            route.setCreaterId(customer.getId());

            TravelAgency travelAgency = travelAgencyMapper.selectByPrimaryKey(params.get("travelAgencyId") + "");
            if (travelAgency == null) {
                throw new ServiceException("未找到指定的假期信息，请检查！");
            }
            route.setTravelAgencyId(params.get("travelAgencyId") + "");
            route.setSelfSupport(travelAgency.getSelfSupport());
            if (StringUtils.isEmpty(params.get("id") + "")) {
                id = getUUID();
                route.setId(id);
                route.setCreaterId(customer.getId());
                route.setCreatTime(new Date());
                routeMapper.insertSelective(route);
            } else {
                id = route.getId();
                route.setLastmodifyTime(new Date());
                route.setLastModifyById(customer.getId());
                route.setLastModifyByName(customer.getRealName());
                routeMapper.updateByPrimaryKeySelective(route);
                List<TourRouteDay> days = getRouteDaysByRouteId(route.getId());
                for (TourRouteDay day : days) {
                    deleteRouteDayDetailsByDayId(day.getId());
                }
                deleteRouteDaysByRouteId(route.getId());
            }
            if (!ValidUtil.isEmpty(params.get("logoUrl") + "")) {
                List<Images> imagesList;
                Images images;

                Map<String, Object> imgparams = new HashMap<>();
                imgparams.put("valueId", route.getId());
                imgparams.put("cover", "1");
                imagesList = imageService.selectByparams(imgparams);
                if (ValidUtil.isEmpty(imagesList)) {
                    images = new Images();
                    images.setId(getUUID());
                    images.setPath(params.get("logoUrl") + "");
                    images.setCreateTime(new Date());
                    images.setValueId(id);
                    images.setCover("1");
                    imageService.insert(images);
                } else {
                    images = imagesList.get(0);
                    images.setPath(params.get("logoUrl") + "");
                    imageService.update(images);
                }

            }

            JSONArray jsonArray = JSON.parseArray(params.get("trip") + "");
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject iTrip = jsonArray.getJSONObject(i);
                TourRouteDay day = new TourRouteDay();
                day.setDayNo(iTrip.getShort("dayNo"));
                day.setTitle(iTrip.getString("title"));
                day.setTourRouteId(route.getId());
                day.setId(getUUID());
                dayMapper.insertSelective(day);

                JSONArray activities = iTrip.getJSONArray("activities");
                for (int j = 0; j < activities.size(); j++) {
                    JSONObject activity = activities.getJSONObject(j);
                    TourRouteDayDetail dayDetail = new TourRouteDayDetail();
                    dayDetail.setSort(activity.getInteger("sortNo"));
                    dayDetail.setTitle(activity.getString("title"));
                    dayDetail.setContent(activity.getString("content"));
                    dayDetail.setTypeId(activity.getString("typeId"));
                    dayDetail.setTourRouteDayId(day.getId());
                    dayDetail.setId(getUUID());
                    dayDetailMapper.insertSelective(dayDetail);
                }
            }
        } catch (NumberFormatException ne) {
            ne.printStackTrace();
            throw new ServiceException("数字转换错误！");
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("保存线路信息出错！");
        }
    }

    @Override
    public void deleteRouteInfoById(String routeId) {
        TourRoute route = routeMapper.selectByPrimaryKey(routeId);
        if (ValidUtil.isEmpty(route)) {
            throw new ServiceException("未找到对应的线路，请检查！");
        }
//        List<TourRouteDay> days = getRouteDaysByRouteId(routeId);
//        for(TourRouteDay day:days){
//            deleteRouteDayDetailsByDayId(day.getId());
//        }
//        deleteRouteDaysByRouteId(routeId);
        if (route.getStatus().equals(Constants.RES_STATUS_NORMAL)) {
            route.setStatus(Constants.RES_STATUS_DELETE);
        } else {
            route.setStatus(Constants.RES_STATUS_NORMAL);
        }
        routeMapper.updateByPrimaryKeySelective(route);
    }

    @Override
    public TourRoute getRouteById(String routeId) {
        return routeMapper.selectByPrimaryKey(routeId);
    }

    @Override
    public List<TourRouteDay> getRouteDaysByRouteId(String routeId) {
        TourRouteDayExample example = new TourRouteDayExample();
        example.createCriteria().andTourRouteIdEqualTo(routeId);
        example.setOrderByClause("day_no asc");
        return dayMapper.selectByExample(example);
    }

    @Override
    public List<TourRouteDayDetail> getRouteDayDetailsByDayId(String routeDayId) {
        TourRouteDayDetailExample example = new TourRouteDayDetailExample();
        example.createCriteria().andTourRouteDayIdEqualTo(routeDayId);
        example.setOrderByClause("sort asc");
        return dayDetailMapper.selectByExample(example);
    }

    @Override
    public void deleteRouteDaysByRouteId(String routeId) {
        TourRouteDayExample example = new TourRouteDayExample();
        example.createCriteria().andTourRouteIdEqualTo(routeId);
        dayMapper.deleteByExample(example);
    }

    @Override
    public void deleteRouteDayDetailsByDayId(String routeDayId) {
        TourRouteDayDetailExample example = new TourRouteDayDetailExample();
        example.createCriteria().andTourRouteDayIdEqualTo(routeDayId);
        dayDetailMapper.deleteByExample(example);
    }

    public String getUUID() {
        return String.valueOf(snowflakeIdWorker.nextId());
    }

    @Override
    public List<Map<String, Object>> getByParams(Map<String, Object> params) {
        return routeMapper.selectByParams(params);
    }

    @Override
    public List<Map<String, Object>> queryByParams(Map<String, Object> params) {
        return routeMapper.queryByParams(params);
    }

    @Override
    public List<Map<String, Object>> getTourDayByRouteId(String id) {
        return dayMapper.selectByRouteId(id);
    }

    @Override
    public TourRouteDayDetail getRouteDayDetailByDetailId(String dayDetailId) {
        return dayDetailMapper.selectByPrimaryKey(dayDetailId);
    }

    @Override
    public List<Map<String, Object>> getTravelAgencyListByParams(Map<String, Object> params) {
        return routeMapper.getTravelAgencyListByParams(params);
    }

    @Override
    public List<FullCalendar> getPriceCalendar(Map<String, Object> param) {
        return tourRoutePriceMapper.getPriceCalendar(param);
    }

    @Override
    public List<Map<String, Object>> getPriceCalendar2(Map<String, Object> param) {
        return tourRoutePriceMapper.getPriceCalendar2(param);
    }

    @Override
    public List<FullCalendar> getPriceCalendarForWeixin(Map<String, Object> param) {
        return tourRoutePriceMapper.getPriceCalendarForWeixin(param);
    }

    @Override
    public List<Map<String, Object>> queryPriceByParams(Map<String, Object> params) {
        return tourRoutePriceMapper.queryPriceByParams(params);
    }

    @Override
    public void order(TourRouteOrder order, CustomerCoupon customerCoupon, String travelerInfo, BillInfo billInfo,String customerId) throws ServiceException {
        Map<String,Object> param = new HashMap<>();

        if (StringUtils.isEmpty(travelerInfo)) {
            throw new ServiceException("请至少添加一名旅客信息！");
        }
//        order.setId(getUUID());
        tourRouteOrderMapper.insertSelective(order);
        if (billInfo != null) {
            billInfo.setOrderId(order.getId());
            billInfo.setPrice(order.getPrice());
            billInfoMapper.insertSelective(billInfo);
        }

        if (customerCoupon != null) {
            customerCoupon.setUsedTime(new Date());
            customerCouponMapper.updateByPrimaryKey(customerCoupon);
        }
        try {
            JSONArray jsonArray = JSON.parseArray(travelerInfo);
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject iTraveler = jsonArray.getJSONObject(i);
                TourRouteOrderDetail detail = new TourRouteOrderDetail();
                detail.setCustomerIdcard(iTraveler.getString("idCard"));
                detail.setCustomerName(iTraveler.getString("name"));
                detail.setTelephone(iTraveler.getString("tel"));
                detail.setTourRouteOrderId(order.getId());
                detail.setId(getUUID());
                orderDetailMapper.insertSelective(detail);
                Contacts contacts = new Contacts();
                contacts.setIdCard(iTraveler.get("idCard").toString());
                contacts.setName(iTraveler.get("name").toString());
                contacts.setTelephone(iTraveler.get("tel").toString());
                contacts.setUserId(customerId);
                param.clear();
                param.put("userId",customerId);
                param.put("isDefault",true);
                List<Contacts> contactsList = contactsService.selectByParam(param);
                contacts.setIsDefault(true);
                for (Contacts contacts1:contactsList){
                    if (contacts1.getIsDefault()){
                        contacts.setIsDefault(false);
                    }
                }
                param.clear();
                param.put("idCard",contacts.getIdCard());
                param.put("telephone",contacts.getTelephone());
                param.put("name",contacts.getName());
                contactsList = contactsService.selectByParam(param);
                if (contactsList.isEmpty()){
                    contactsService.save(contacts,getUUID());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("保存订单明细出错！");
        }
    }

    @Override
    public void order(TourRouteOrder order, List<TourRouteOrderDetail> details) {
        TourRoute route = routeMapper.selectByPrimaryKey(order.getTourRouteId());
        if (route == null) {
            throw new ServiceException("未找到指定的线路信息！");
        }
        order.setId(getUUID());
        Calendar cal = Calendar.getInstance();
        cal.setTime(order.getStartDate());
        cal.add(Calendar.DATE, route.getTourDay());
        order.setEndDate(cal.getTime());
        order.setStatus("0");
        order.setInTime(new Date());

        if (details == null || details.size() == 0) {
            throw new ServiceException("请至少添加一名旅客信息！");
        }
        tourRouteOrderMapper.insertSelective(order);
        for (int i = 0; i < details.size(); i++) {
            TourRouteOrderDetail detail = details.get(i);
            detail.setTourRouteOrderId(order.getId());
            detail.setId(getUUID());
            orderDetailMapper.insertSelective(detail);
        }
    }

    @Override
    public List<Map<String, Object>> getTourRouteTypeInfo(Map<String, Object> params) {
        return routeMapper.getTourRouteTypeInfo(params);
    }

    @Override
    public Map<String, List<String>> getIndexData(Integer num, String customerId) {
        Map<String, List<String>> hotelIndex = new HashMap<>();
        Date endDate = new Date();
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, -num);
        c.set(Calendar.DAY_OF_MONTH, 1);
        Date startDate = c.getTime();
        Map<String, Object> param = new HashMap<>();
        param.put("endDate", endDate);
        param.put("startDate", startDate);
        if (!ValidUtil.isEmpty(customerId)) {
            param.put("customerId", customerId);
        }
        hotelIndex.put("orderNumber", tourRouteOrderMapper.orderIndex(param));
        hotelIndex.put("orderAmount", tourRouteOrderMapper.orderPriceIndex(param));

        hotelIndex.put("orderDate", tourRouteOrderMapper.orderDateIndex(param));
        return hotelIndex;
    }

    @Override
    public TourRoutePrice selectByTourRoutePrice(TourRoutePrice tourRoutePrice) {

        return tourRoutePriceMapper.selectByTourRoutePrice(tourRoutePrice);
    }

    @Override
    public void updatePrice(TourRoutePrice record) {
        tourRoutePriceMapper.updatePrice(record);
    }

    @Override
    public void insertTourRoutePrice(TourRoutePrice recorde) {
        tourRoutePriceMapper.insertSelective(recorde);
    }

    @Override
    public void updateTourRoutePrice(TourRoutePrice recorde) {
        tourRoutePriceMapper.updateByPrimaryKeySelective(recorde);
    }

    @Override
    public TourRoutePrice getTourRoutePrice(Map<String, Object> params) {
        return tourRoutePriceMapper.queryByParams(params);
    }

    @Override
    public Integer getMinReserve(String id, String startDate) {
        Map<String, Object> params = new HashMap<>();
        params.put("id", id);
        params.put("startDate", startDate);
        try {
            return tourRoutePriceMapper.getMinReserve(params);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    @Override
    public TourRoute selectByPrimaryKey(String id) {
        return routeMapper.selectByPrimaryKey(id);
    }

    @Override
    public void update(TourRoute entity) {
        routeMapper.updateByPrimaryKey(entity);
    }

    @Override
    public Map<String, Object> getOnePrice(String tourId) {
        return routeMapper.getOnePrice(tourId);
    }
}
